package qc.module.ehs.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.constants.QCConstant;
import qc.common.core.enums.EhsTaskCategoryTypeEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.IdentifierUtil;
import qc.module.ehs.dto.taskbench.TaskBenchQueryConditionDto;
import qc.module.ehs.dto.taskconsole.TaskConsoleUnitTaskItemPaginationQueryConditionDto;
import qc.module.ehs.dto.taskconsole.TaskConsoleUnitTaskItemQueryConditionDto;
import qc.module.ehs.dto.taskexecute.TaskExecuteInfoDto;
import qc.module.ehs.dto.taskitem.TaskItemInfoDto;
import qc.module.ehs.dto.taskitem.TaskItemPaginationQueryResultDto;
import qc.module.ehs.dto.taskitem.TaskItemTransmitDto;
import qc.module.ehs.entity.EhsTaskItem;
import qc.module.ehs.mapper.EhsTaskItemMapper;
import qc.module.ehs.repository.EhsTaskItemRepository;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 安全任务项Service
 * @author QuCheng Tech
 * @since 2024/11/13
 */
@Service
public class EhsTaskItemService {

    @Autowired
    private EhsTaskItemRepository repository;

    @Autowired
    private EhsTaskExecService taskExecService;

    /**
     * 设置指定任务项状态为完成
     * 设置指定的任务项为已完成；需要判断任务项的状态及任务项执行记录的确认状态；
     * @param taskItemId 任务项ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public String finish(String taskItemId) {
        if (StringUtils.isBlank(taskItemId))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");

        //获取指定任务项
        EhsTaskItem item = repository.selectById(taskItemId);
        if (item == null)
            return QCUnifyReturnValue.Warn("任务项信息不存在");

        //设置任务项完成需要同时满足以下条件，不满足时需要进行对应的提示：
        //1.任务项的属性：任务是否执行完成为false、任务是否终止/取消为false；
        //2.任务项对应的执行记录必须大于0；没有执行记录不能完成；
        //3.任务项对应的执行记录必须每条的是否确认通过均为true；

        if (item.getHasfinish() || item.getHasend()) {
            return QCUnifyReturnValue.Warn("指定任务项已经执行完成或者终止，不再进行完成操作。");
        }

        //获取指定任务项的所有执行记录，判断执行记录的确认状态，只要有一个执行记录未确认则提示
        List<TaskExecuteInfoDto> executeInfos = taskExecService.getTaskItemExecutes(taskItemId);
        if (CollectionUtils.isEmpty(executeInfos))
            return QCUnifyReturnValue.Warn("指定任务项没有执行记录，不能进行完成操作。");
        //获取任务项未确认的执行记录
        List<TaskExecuteInfoDto> notConfirmInfo = executeInfos.stream()
                .filter(p -> p.isHasconfirm() == false).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(notConfirmInfo))
            return QCUnifyReturnValue.Warn("指定任务项存在未确认的执行记录，无法进行完成操作。");

        //修改任务项状态为已完成
        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();

        wrapper.set(EhsTaskItem::getHasfinish, true);

        wrapper.eq(EhsTaskItem::getItemid, taskItemId);

        repository.update(null, wrapper);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 设置指定任务项状态为终止
     * 设置指定的任务项为终止/取消；需要判断任务项的状态及任务项执行记录的确认状态；
     * @param taskItemId 任务项ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public String end(String taskItemId) {
        if (StringUtils.isBlank(taskItemId))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");

        //获取指定任务项
        EhsTaskItem item = repository.selectById(taskItemId);
        if (item == null)
            return QCUnifyReturnValue.Warn("任务项信息不存在");

        //判断任务状态要求：未完成、未终止
        if (item.getHasfinish() == true)
            return QCUnifyReturnValue.Warn("当前任务项状态为已完成，不能进行终止操作。");
        if (item.getHasend() == true)
            return QCUnifyReturnValue.Warn("当前任务项为终止状态，无需重复操作。");

        //获取指定任务项的所有执行记录，判断执行记录的确认状态，只要有一个执行记录未确认则提示
        List<TaskExecuteInfoDto> executeInfos = taskExecService.getTaskItemExecutes(taskItemId);
        if (CollectionUtils.isNotEmpty(executeInfos)) {
            List<TaskExecuteInfoDto> notConfirmInfo = executeInfos.stream()
                    .filter(p -> p.isHasconfirm() == false).collect(Collectors.toList());
            if (CollectionUtils.isNotEmpty(notConfirmInfo))
                return QCUnifyReturnValue.Warn("指定任务项还有未确认的执行记录，无法进行终止操作。");
        }

        //修改任务项状态为已终止/取消
        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();

        wrapper.set(EhsTaskItem::getHasend, true);

        wrapper.eq(EhsTaskItem::getItemid, taskItemId);

        repository.update(null, wrapper);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 设置指定任务项状态为继续
     * <p>
     * 设置指定的任务项为继续；需要判断任务项的状态及任务项执行记录的确认状态；
     * @param taskItemId 任务项ID
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public String setContinue(String taskItemId) {
        if (StringUtils.isBlank(taskItemId))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");

        //获取指定任务项
        EhsTaskItem item = repository.selectById(taskItemId);
        if (item == null)
            return QCUnifyReturnValue.Warn("任务项信息不存在");

        //判断任务状态要求：未完成、已终止
        if (item.getHasfinish() == true)
            return QCUnifyReturnValue.Warn("当前任务项状态为已完成，不能进行继续操作。");
        if (item.getHasend() != true)
            return QCUnifyReturnValue.Warn("当前任务项不是终止状态，不能进行继续操作。");

        //判断任务项的状态：如果已终止/取消，则修改任务项状态终止/取消为false
        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();

        wrapper.set(EhsTaskItem::getHasend, false);

        wrapper.eq(EhsTaskItem::getItemid, taskItemId);

        repository.update(null, wrapper);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 转交指定的任务项
     * <p>
     * 如果当前责任部门/人为空，设置的转交部门/人不能是责任部门/参与组员；
     * 如果当前责任部门/人不为空，设置的转交部门/人不能当前责任部门/人；
     * @param dto 转交DTO
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public String transmit(TaskItemTransmitDto dto) {
        if (dto == null) return QCUnifyReturnValue.Warn("请求对象不能为空");
        if (StringUtils.isBlank(dto.getItemid()))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");
        //传入的部门ID和人员ID均无效进行错误提示；转交指定的部门和人员必须至少有1个；
        if ((dto.getTransdeptid() == null || dto.getTransdeptid() <= 0x0) &&
                (dto.getTransuserid() == null || dto.getTransuserid() <= 0x0)) {
            return QCUnifyReturnValue.Warn("转交指定的部门和人员无效，至少有一个。");
        }

        //获取指定任务项
        EhsTaskItem item = repository.selectById(dto.getItemid());
        if (item == null)
            return QCUnifyReturnValue.Warn("任务项信息不存在");

        //判断任务的转交状态：如果任务的转交是否接收为false（可能时转交未接收、也可能时转交被拒收）均可以进行转交操作
        if (item.getTranshasreceive() == true)
            return QCUnifyReturnValue.Warn("当前任务已转交完成，由转交接收部门/人员进行处理，需要由转交接收部门/人员退回后才能再次进行转交操作。");

        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();

        //判断任务项的当前责任部门/责任人是否为空：
        // 如果为空则设置的转交部门/人不能是责任部门/参与组员；，如果不为空则设置的转交部门/人不能当前责任部门/人；
        if (dto.getTransdeptid() != null && dto.getTransdeptid() > 0x0) {
            if (item.getTransdeptid() == null || item.getTransdeptid() < 0x1) {
                if (dto.getTransdeptid() == item.getResdeptid()) {
                    return QCUnifyReturnValue.Warn("转交部门不能是责任部门。");
                } else {
                    wrapper.set(EhsTaskItem::getTransdeptid, dto.getTransdeptid());
                    wrapper.set(EhsTaskItem::getTransdeptname, dto.getTransdeptname());
                }
            } else {
                if (dto.getTransdeptid() == item.getTransdeptid()) {
                    //已有转交部门就是本次进行转交的部门
                    if (item.getTranshasreceive() == true) {
                        //已确认接收转交不需要重复进行转交
                        return QCUnifyReturnValue.Warn("当前任务已转交给该部门，已被接收，请无重复操作。");
                    } else {
                        //转交没有确认或拒收
                        if (item.getTransreceivetm() != null) {
                            //转交已经被拒收
                            return QCUnifyReturnValue.Warn("当前任务已转交给该部门，已被拒绝接收，请无重复操作。");
                        } else {
                            //转交未被接收也未拒收
                            return QCUnifyReturnValue.Warn("当前任务已转交给该部门，转交未被确认，请勿重复操作。");
                        }
                    }
                } else {
                    wrapper.set(EhsTaskItem::getTransdeptid, dto.getTransdeptid());
                    wrapper.set(EhsTaskItem::getTransdeptname, dto.getTransdeptname());
                }
            }
        }

        if (dto.getTransuserid() != null && dto.getTransuserid() > 0x0) {
            if (item.getTransuserid() == null || item.getTransuserid() < 0x1) {
                if (dto.getTransuserid() == item.getResuserid1() || dto.getTransuserid() == item.getResuserid2()) {
                    return QCUnifyReturnValue.Warn("转交人不能是参与组员。");
                } else {
                    wrapper.set(EhsTaskItem::getTransuserid, dto.getTransuserid());
                    wrapper.set(EhsTaskItem::getTransusername, dto.getTransusername());
                }
            } else {
                if (dto.getTransuserid() == item.getTransuserid()) {
                    //已有的转交人就是本次进行转交的人
                    if (item.getTranshasreceive() == true) {
                        //已确认接收转交不需要重复进行转交
                        return QCUnifyReturnValue.Warn("当前任务已转交给该人员，已被接收，请无重复操作。");
                    } else {
                        //转交没有确认或拒收
                        if (item.getTransreceivetm() != null) {
                            //转交已经被拒收
                            return QCUnifyReturnValue.Warn("当前任务已转交给该人员，已被拒绝接收，请无重复操作。");
                        } else {
                            //转交未被接收也未拒收
                            return QCUnifyReturnValue.Warn("当前任务已转交给该人员，转交未被确认，请勿重复操作。");
                        }
                    }
                } else {
                    wrapper.set(EhsTaskItem::getTransuserid, dto.getTransuserid());
                    wrapper.set(EhsTaskItem::getTransusername, dto.getTransusername());
                }
            }
        }

        //修改任务项
        //修改任务项信息中固定设置转交是否接收为false、接收确认时间为null
        wrapper.set(EhsTaskItem::getTranshasreceive, false);
        wrapper.set(EhsTaskItem::getTransreceivetm, null);

        wrapper.eq(EhsTaskItem::getItemid, item.getItemid());

        repository.update(null, wrapper);

        return QCUnifyReturnValue.Success();
    }

    /***
     *取消/退回转交任务项
     *
     * @param taskItemId 任务项ID
     * @param isCancel 是否为取消转交操作，true表示为取消转交，false为退回转交
     * @return java.lang.String
     * @author QuCheng Tech
     * @since 2025/2/24
     */
    public String cancelTransmit(String taskItemId, boolean isCancel) {
        if (StringUtils.isBlank(taskItemId))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");

        //获取指定任务项
        EhsTaskItem item = repository.selectById(taskItemId);
        if (item == null)
            return QCUnifyReturnValue.Warn("任务项信息不存在");

        //判断是否有转交
        if ((item.getTransdeptid() == null || item.getTransdeptid() < 0x1)
                && (item.getTransuserid() == null || item.getTransuserid() < 0x1))
            return QCUnifyReturnValue.Warn("当前任务项没有进行转交");

        if (isCancel) {
            //为取消转交操作
            if (item.getTranshasreceive() == true)
                return QCUnifyReturnValue.Warn("当前任务项转交已经被确认接收");
        } else {
            //为转交退回操作
            if (item.getTranshasreceive() != true)
                return QCUnifyReturnValue.Warn("当前任务项转交未被接收");
        }

        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();

        wrapper.set(EhsTaskItem::getTransdeptid, null);
        wrapper.set(EhsTaskItem::getTransdeptname, null);
        wrapper.set(EhsTaskItem::getTransuserid, null);
        wrapper.set(EhsTaskItem::getTransusername, null);
        wrapper.set(EhsTaskItem::getTranshasreceive, false);
        wrapper.set(EhsTaskItem::getTransreceivetm, null);

        wrapper.eq(EhsTaskItem::getItemid, taskItemId);

        repository.update(null, wrapper);

        return QCUnifyReturnValue.Success();
    }

    /***
     *确认接收转交任务项
     *
     * @param taskItemId 任务项ID
     * @return java.lang.String
     * @author QuCheng Tech
     * @since 2025/2/21
     */
    public String fulfillTransmit(String taskItemId) {
        if (StringUtils.isBlank(taskItemId))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");

        //获取指定任务项
        EhsTaskItem item = repository.selectById(taskItemId);
        if (item == null)
            return QCUnifyReturnValue.Warn("任务项信息不存在");

        //判断是否有转交
        if ((item.getTransdeptid() == null || item.getTransdeptid() < 0x1)
                && (item.getTransuserid() == null || item.getTransuserid() < 0x1))
            return QCUnifyReturnValue.Warn("当前任务项没有进行转交");

        if (item.getTranshasreceive() == true)
            return QCUnifyReturnValue.Warn("当前任务项转交已经被确认接收");
        //判断任务项转交是否被拒收；不需要进行该判断，因为拒收后在任务查询中不再作为接收人的待办，也无法进行操作
        //if (item.getTransreceivetm() != null)
        //    return QCUnifyReturnValue.Warn("当前任务项转交已经被拒绝接收");

        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();

        wrapper.set(EhsTaskItem::getTranshasreceive, true);
        wrapper.set(EhsTaskItem::getTransreceivetm, DateUtil.getNowDate());

        wrapper.eq(EhsTaskItem::getItemid, taskItemId);

        repository.update(null, wrapper);

        return QCUnifyReturnValue.Success();
    }

    /***
     *拒收转交任务项
     *
     * @param taskItemId 任务项ID
     * @return java.lang.String
     * @author QuCheng Tech
     * @since 2025/2/21
     */
    public String rejectTransmit(String taskItemId) {
        if (StringUtils.isBlank(taskItemId))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");

        //获取指定任务项
        EhsTaskItem item = repository.selectById(taskItemId);
        if (item == null)
            return QCUnifyReturnValue.Warn("任务项信息不存在");

        //判断是否有转交
        if ((item.getTransdeptid() == null || item.getTransdeptid() < 0x1)
                && (item.getTransuserid() == null || item.getTransuserid() < 0x1))
            return QCUnifyReturnValue.Warn("当前任务项没有进行转交");

        if (item.getTranshasreceive() == true)
            return QCUnifyReturnValue.Warn("当前任务项转交已经被确认接收");
        //判断任务项转交是否被拒收；不需要进行该判断，因为拒收后在任务查询中不再作为接收人的待办，也无法进行操作
        //确认接收的转交任务不能再变为拒收，只能退回
        //if (item.getTransreceivetm() != null)
        //    return QCUnifyReturnValue.Warn("当前任务项转交已经被拒绝接收");

        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();

        wrapper.set(EhsTaskItem::getTranshasreceive, false);
        wrapper.set(EhsTaskItem::getTransreceivetm, DateUtil.getNowDate());

        wrapper.eq(EhsTaskItem::getItemid, taskItemId);

        repository.update(null, wrapper);

        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取指定分组的所有任务项
     * @param groupId 分组ID
     * @return List<TaskItemInfoDto>
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    public List<TaskItemInfoDto> getItemsByGroupId(String groupId) {

        //同一个任务分组中的任务项均按照计划开始时间升序、任务项名称升序；
        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskItem::getGroupid, groupId)
                .orderByAsc(EhsTaskItem::getPlanbegintm, EhsTaskItem::getItemname);
        List<EhsTaskItem> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            return EhsTaskItemMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 获取指定任务和指定任务分组的任务项集合
     * @param taskId   任务ID
     * @param groupIds 任务分组ID集合
     * @return List<TaskItemInfoDto>
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public List<TaskItemInfoDto> getItemsByTaskIdAndGroupIds(String taskId, List<String> groupIds) {

        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskItem::getTaskid, taskId)
                .in(EhsTaskItem::getGroupid, groupIds);
        List<EhsTaskItem> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            return EhsTaskItemMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 批量删除任务项
     * @param ids 任务项ID集合
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/14
     */
    public String deleteByIds(List<String> ids) {
        repository.deleteBatchIds(ids);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 新增任务项
     * @param item 任务项对象
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    public String add(EhsTaskItem item) {
        if (item == null) return QCUnifyReturnValue.Warn("任务项对象不能为空");
        if (StringUtils.isBlank(item.getTaskid())) return QCUnifyReturnValue.Warn("任务ID不能为空");
        if (StringUtils.isBlank(item.getGroupid())) return QCUnifyReturnValue.Warn("任务分组ID不能为空");
        if (StringUtils.isBlank(item.getOrgcode())) return QCUnifyReturnValue.Warn("所属组织代码不能为空");
        if (StringUtils.isBlank(item.getCatname())) return QCUnifyReturnValue.Warn("任务分类名称不能为空");
        if (item.getTasktype() == null) return QCUnifyReturnValue.Warn("任务大类不能为空");
        if (StringUtils.isBlank(item.getPlantmstr())) return QCUnifyReturnValue.Warn("计划时间周期文字不能为空");
        if (item.getPlanbegintm() == null) return QCUnifyReturnValue.Warn("计划开始时间不能为空");
        if (item.getPlanendtm() == null) return QCUnifyReturnValue.Warn("计划截止时间不能为空");
        if (item.getPlanfrequencytype() == null) return QCUnifyReturnValue.Warn("周期类型不能为空");
        if (item.getPlanfrequencycount() == null) return QCUnifyReturnValue.Warn("周期内计划执行次数不能为空");
        if (item.getHasfinish() == null) return QCUnifyReturnValue.Warn("任务项是否执行完成不能为空");
        if (item.getHasend() == null) return QCUnifyReturnValue.Warn("任务项是否终止/取消不能为空");
        if (item.getExeccount() == null) return QCUnifyReturnValue.Warn("实际执行次数不能为空");
        if (item.getExecidentifycount() == null) return QCUnifyReturnValue.Warn("辨识危险源次数不能为空");
        if (item.getExectroublecount() == null) return QCUnifyReturnValue.Warn("上报隐患次数不能为空");

        if (StringUtils.isBlank(item.getItemid())) item.setItemid(IdentifierUtil.randomUUID());
        //新增任务项时，固定设置转交是否接收为false、转交接收时间为null
        item.setTranshasreceive(false);
        item.setTransreceivetm(null);

        if (repository.insert(item) < 0x1) {
            return QCUnifyReturnValue.Warn("新增任务项失败");
        }
        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取指定任务项
     * @param id      任务项ID
     * @param userId  当前操作的用户ID，用于判断是否为任务项中的转交接收人；为0时不判断；
     * @param deptIds 当前操作用户作为负责人的部门ID集合，用于判断是否为任务项中的转交接收人；为空时不判断；
     * @return TaskItemInfoDto
     * @author QuCheng Tech
     * @since 2024/11/29
     */
    public TaskItemInfoDto get(String id, int userId, int[] deptIds) {
        EhsTaskItem en = getEntity(id);
        if (en != null) {
            TaskItemInfoDto dto = EhsTaskItemMapper.MAPPER.toDto(en);
            //先设置任务项中的转交人表示为false
            dto.setIstransreceiver(false);

            if (userId > 0x0 && en.getTransuserid() != null && en.getTransuserid().intValue() == userId) {
                dto.setIstransreceiver(true);
            } else if (deptIds != null && deptIds.length > 0x0
                    && en.getTransdeptid() != null && en.getTransdeptid().intValue() > 0x0
                    && Arrays.stream(deptIds).anyMatch(p -> p == en.getTransdeptid().intValue())
            ) {
                dto.setIstransreceiver(true);
            }

            return dto;
        }
        return null;
    }

    /***
     * 获取指定ID的任务项Entity
     *
     * @param taskItemId 任务项ID
     * @return qc.module.ehs.entity.EhsTaskItem
     * @author QuCheng Tech
     * @since 2025/3/10
     */
    public EhsTaskItem getEntity(String taskItemId) {
        if (StringUtils.isNotBlank(taskItemId))
            return repository.selectById(taskItemId);
        return null;
    }

    /**
     * 查询任务 -- 任务工作台
     * <p>
     * 获取个人的待办、已办任务列表；后台接口不管DTO中的任务状态标记；
     * 查询的结果按照计划截止时间升序排列；
     * @param condition 查询条件
     * @param userId    当前用户
     * @param deptIds   当前用户负责的部门ID集合
     * @return TaskBenchQueryResultDto
     * @author QuCheng Tech
     * @since 2024/11/15
     */
    public TaskItemPaginationQueryResultDto query(TaskBenchQueryConditionDto condition,
                                                  Integer userId, int[] deptIds) throws QCPromptException {
        //1.查询条件有效性验证
        if (condition == null)
            throw new QCPromptException("查询任务列表的条件对象不能为空");
        if (StringUtils.isBlank(condition.getOrgcode()))
            throw new QCPromptException("查询任务列表的组织机构代码不能为空");
        if (StringUtils.isBlank(condition.getBegintm()))
            throw new QCPromptException("查询任务列表的起始时间不能为空");
        if (StringUtils.isBlank(condition.getEndtm()))
            throw new QCPromptException("查询任务列表的截止时间不能为空");

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (StringUtils.isNotBlank(condition.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }

        //2.设置返回结果默认值
        TaskItemPaginationQueryResultDto result = new TaskItemPaginationQueryResultDto();
        result.setTotal(0x0);
        result.setPages(0x1);
        result.setItems(new ArrayList<>());

        //3.构建任务项查询条件
        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        //组织机构代码，必须有，判断相等
        wrapper.eq(EhsTaskItem::getOrgcode, condition.getOrgcode());
        /*任务项的时间条件判断需要考虑以下几种不同情况：
            1.查询的起止时间前后都包含计划时间，查询时间段包含整个计划时间段；
            pbtm>=tm1 and petm<=tm2
            2.查询的起止时间前后都被计划时间包含，查询的时间段是计划时间段中间的部分时间；
            pbtm<=tm1 and petm>=tm2
            3.查询的起始时间被计划时间包含，查询时间段包含计划时间中的前部分时间；
            查询的截止时间被计划时间包含，查询时间段包含计划时间中的后部分时间；
            pbtm<=tm2 and petm>=tm1
        */
        Date finalBeginDate = beginDate;
        Date finalEndDate = endDate;
        wrapper.and(q -> {
            (q.ge(EhsTaskItem::getPlanbegintm, finalBeginDate).le(EhsTaskItem::getPlanendtm, finalEndDate)).or()
                    .le(EhsTaskItem::getPlanbegintm, finalBeginDate).ge(EhsTaskItem::getPlanendtm, finalEndDate).or()
                    .le(EhsTaskItem::getPlanbegintm, finalEndDate).ge(EhsTaskItem::getPlanendtm, finalBeginDate);
        });

        //任务状态标记：0表示待办、1表示已办、其他表示全部；
        if (condition.getFlag() == 0x0) {
            //查询待办
            //任务状态：执行完成为false并且取消/终止为false
            wrapper.eq(EhsTaskItem::getHasfinish, false)
                    .eq(EhsTaskItem::getHasend, false);
        } else if (condition.getFlag() == 0x1) {
            //查询已办
            //任务状态：执行完成为true或者取消/终止为true
            //wrapper.eq(EhsTaskItem::getHasfinish,true).or()
            //        .eq(EhsTaskItem::getHasend,true);
            //OR条件需要使用括号包裹，否则导致查询条件错误
            wrapper.and(q -> {
                q.eq(EhsTaskItem::getHasfinish, true).or().eq(EhsTaskItem::getHasend, true);
            });
        }

        //分为是否有传入部门ID集合2种情况处理
        if (deptIds != null && deptIds.length > 0x0) {
            //有传入部门ID集合，匹配用户负责的部门ID集合中有当前责任部门ID或者当前责任人ID为用户ID，
            // 或者匹配用户负责的部门ID集合中有责任部门ID或者参与组员ID为用户ID
            //转交任务需要确认后，如果转交任务已确认拒收，此时任务项不出现在待办或已办中
            wrapper.and(q -> {
                // Resdeptid in deptIds or Resuserid1 = userId or  Resuserid2 = userId
                // or ((Transdeptid in deptIds or Transuserid = userId) and (Transhasreceive = true or (Transhasreceive = false and Transreceivetm is null)))
                q.in(EhsTaskItem::getResdeptid, deptIds)
                        .or().eq(EhsTaskItem::getResuserid1, userId)
                        .or().eq(EhsTaskItem::getResuserid2, userId)
                        .or(q1 -> {
                            q1.and(q2 -> {
                                q2.in(EhsTaskItem::getTransdeptid, deptIds).or().eq(EhsTaskItem::getTransuserid, userId);
                            }).and(q2 -> {
                                q2.eq(EhsTaskItem::getTranshasreceive, true).or(q3 -> {
                                    q3.eq(EhsTaskItem::getTranshasreceive, false).isNull(EhsTaskItem::getTransreceivetm);
                                });
                            });
                        });
            });
        } else {
            //未传入部门ID集合，匹配当前责任人ID为用户ID或者匹配参与组员ID为用户ID
            // Resuserid1 = userId or  Resuserid2 = userId
            // or (Transuserid = userId and (Transhasreceive = true or (Transhasreceive = false and Transreceivetm is null)))
            wrapper.and(q -> {
                q.eq(EhsTaskItem::getResuserid1, userId)
                        .or().eq(EhsTaskItem::getResuserid2, userId)
                        .or(q1 -> {
                            q1.eq(EhsTaskItem::getTransuserid, userId).and(q2 -> {
                                q2.eq(EhsTaskItem::getTranshasreceive, true).or(q3 -> {
                                    q3.eq(EhsTaskItem::getTranshasreceive, false).isNull(EhsTaskItem::getTransreceivetm);
                                });
                            });
                        });
            });
        }

        //关键字：可以匹配单元名称、设备设施名称、危险源名称、责任部门名称、参与组员名称、当前责任部门名称、当前责任人名称、任务项名称
        if (StringUtils.isNotBlank(condition.getKeywords())) {
            wrapper.and(q -> {
                q.like(EhsTaskItem::getUnitname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getFacilityname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getHazardname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getResdeptname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getResusername1, condition.getKeywords()).or()
                        .like(EhsTaskItem::getResusername2, condition.getKeywords()).or()
                        .like(EhsTaskItem::getTransdeptname, condition.getKeywords()).or()
                        .like(EhsTaskItem::getTransusername, condition.getKeywords()).or()
                        .like(EhsTaskItem::getItemname, condition.getKeywords());
            });
        }

        //如果传入单元ID、危险源ID、设备设施ID
        if (StringUtils.isNotBlank(condition.getUnitid())) {
            wrapper.eq(EhsTaskItem::getUnitid, condition.getUnitid());
        }
        if (StringUtils.isNotBlank(condition.getHazardid())) {
            wrapper.eq(EhsTaskItem::getHazardid, condition.getHazardid());
        }
        if (StringUtils.isNotBlank(condition.getFacilityid())) {
            wrapper.eq(EhsTaskItem::getFacilityid, condition.getFacilityid());
        }

        //按计划截止时间升序
        wrapper.orderByAsc(EhsTaskItem::getPlanendtm);

        //分页查询
        // 先构造一个Page对象
        int pageNum = QCConstant.PAGEING_DEFAULT_PAGE_NUM;
        int pageSize = QCConstant.PAGEING_DEFAULT_PAGE_SIZE;
        if (condition.getPage() > 0x0)
            pageNum = condition.getPage();
        if (condition.getPageSize() > 0x0)
            pageSize = condition.getPageSize();

        IPage<EhsTaskItem> page = new Page<>(pageNum, pageSize);
        IPage<EhsTaskItem> pageResult = repository.selectPage(page, wrapper);
        //获取查询结果
        result.setTotal(pageResult.getTotal());
        result.setPages(pageResult.getPages());
        List<EhsTaskItem> ens = pageResult.getRecords();
        if (CollectionUtils.isNotEmpty(ens)) {
            //需要根据转交的接收部门和接收人判断当前用户是否为接收人
            List<TaskItemInfoDto> items = new ArrayList<>();
            for (EhsTaskItem en : ens) {
                TaskItemInfoDto itemInfoDto = EhsTaskItemMapper.MAPPER.toDto(en);

                //判断任务是否有转交
                if (en.getTransuserid() != null && userId != null && en.getTransuserid().intValue() == userId.intValue()) {
                    //转交接收人就是当前用户ID
                    itemInfoDto.setIstransreceiver(true);
                } else if (en.getTransdeptid() != null && deptIds != null && deptIds.length > 0x0) {
                    if (Arrays.stream(deptIds).anyMatch(p -> p == en.getTransdeptid().intValue()))
                        itemInfoDto.setIstransreceiver(true);
                }

                items.add(itemInfoDto);
            }
            result.setItems(items);
        }

        return result;
    }

    /**
     * 查询指定单元的任务项 -- 任务控制台
     * <p>
     * 查询指定单元的任务项，不管任务的责任部门和责任人；任务项的状态可以传入1个或多个；
     * * 从任务项表中进行查询，查询的结果按照计划截止时间升序排列；
     * @param condition 查询条件
     * @return List<TaskItemInfoDto>
     * @author QuCheng Tech
     * @since 2024/12/27
     */
    public List<TaskItemInfoDto> queryUnitTaskItems(TaskConsoleUnitTaskItemQueryConditionDto condition) throws QCPromptException {
        if (condition == null)
            throw new QCPromptException("查询条件对象不能为空");
        if (StringUtils.isBlank(condition.getUnitid()))
            throw new QCPromptException("查询的单元不能为空");
        Date beginTime = null;
        Date endTime = null;
        //查询条件的起止时间需要同时传入
        if (StringUtils.isNotBlank(condition.getBegintm()) && StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                beginTime = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
            try {
                endTime = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
            if (beginTime != null && endTime != null) {
                if (beginTime.after(endTime))
                    throw new QCPromptException("查询条件中的开始时间不能在截止时间之后");
            }
        }

        List<EhsTaskItem> ens = queryTaskItemEntities(null, condition.getUnitid(), beginTime, endTime, condition.getStatus(), null);
        if (CollectionUtils.isNotEmpty(ens)) {
            return EhsTaskItemMapper.MAPPER.toDtoList(ens);
        }

        return null;
    }

    /**
     * 查询指定单元的分页任务项 -- 任务控制台
     * <p>
     * 查询指定单元的任务项，不管任务的责任部门和责任人；任务项的状态可以指定1个或多个；
     * * 从任务项表中进行查询，查询的结果按照计划开始时间升序排列；结果分页显示；
     * @param condition 查询条件
     * @return List<TaskItemInfoDto>
     * @author QuCheng Tech
     * @since 2024/12/27
     */
    public TaskItemPaginationQueryResultDto queryPaginationUnitTaskItems(TaskConsoleUnitTaskItemPaginationQueryConditionDto condition) throws QCPromptException {
        if (condition == null)
            throw new QCPromptException("查询条件对象不能为空");
        if (StringUtils.isBlank(condition.getUnitid()))
            throw new QCPromptException("查询的单元不能为空");
        Date beginTime = null;
        Date endTime = null;
        //查询条件的起止时间需要同时传入
        if (StringUtils.isNotBlank(condition.getBegintm()) && StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                beginTime = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
            try {
                endTime = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }
        if (beginTime.after(endTime))
            throw new QCPromptException("查询条件中的开始时间不能在截止时间之后");

        TaskItemPaginationQueryResultDto result = new TaskItemPaginationQueryResultDto();
        result.setTotal(0x0);
        result.setPages(0x1);
        result.setItems(new ArrayList<>());

        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskItem::getUnitid, condition.getUnitid());
        //判断查询的任务状态:0-待办，1-已办，其他-全部
        if (condition.getStatus() == 0x0) {
            //待办：执行完成为false并且取消/终止为false
            wrapper.eq(EhsTaskItem::getHasfinish, false)
                    .eq(EhsTaskItem::getHasend, false);
        } else if (condition.getStatus() == 0x1) {
            //已办：执行完成为true或者取消/终止为true
            wrapper.and(q -> {
                q.eq(EhsTaskItem::getHasfinish, true).or()
                        .eq(EhsTaskItem::getHasend, true);
            });
        } else {
            //查询任务项状态为全部，不需要进行过滤
        }

        //查询时间过滤
        if (beginTime != null && endTime != null) {
            //查询时间：起始时间 >= 计划开始时间 and 截止时间 <= 计划截止时间
            Date finalBeginTime = beginTime;
            Date finalEndTime = endTime;
            wrapper.and(q -> {
                q.ge(EhsTaskItem::getPlanbegintm, finalBeginTime).le(EhsTaskItem::getPlanendtm, finalEndTime);
            });
        }
        wrapper.orderByAsc(EhsTaskItem::getPlanendtm);

        //分页查询
        // 先构造一个Page对象
        int pageNum = QCConstant.PAGEING_DEFAULT_PAGE_NUM;
        int pageSize = QCConstant.PAGEING_DEFAULT_PAGE_SIZE;
        if (condition.getPage() > 0x0)
            pageNum = condition.getPage();
        if (condition.getPageSize() > 0x0)
            pageSize = condition.getPageSize();

        IPage<EhsTaskItem> page = new Page<>(pageNum, pageSize);
        IPage<EhsTaskItem> pageResult = repository.selectPage(page, wrapper);
        //获取查询结果
        result.setTotal(pageResult.getTotal());
        result.setPages(pageResult.getPages());
        List<EhsTaskItem> ens = pageResult.getRecords();
        if (CollectionUtils.isNotEmpty(ens)) {
            result.setItems(EhsTaskItemMapper.MAPPER.toDtoList(ens));
        }

        return result;
    }

    /**
     * 查询指定设备设施的待办任务 -- 任务控制台
     * <p>
     * 查询指定设备设施的待办任务，不管任务的责任部门和责任人；
     * 从任务项表中进行查询，查询的结果按照计划截止时间升序排列；
     * @param facilityId 设备设施ID
     * @return List<TaskItemInfoDto>
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public List<TaskItemInfoDto> queryTodoByFacilityId(String facilityId) {
        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskItem::getFacilityid, facilityId);

        //查询待办
        //任务状态：执行完成为false并且取消/终止为false
        wrapper.eq(EhsTaskItem::getHasfinish, false)
                .eq(EhsTaskItem::getHasend, false);

        wrapper.orderByAsc(EhsTaskItem::getPlanendtm);

        List<EhsTaskItem> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            return EhsTaskItemMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 查询指定危险源的待办任务 -- 任务控制台
     * <p>
     * 查询指定危险源的待办任务，不管任务的责任部门和责任人；
     * 可以用于查询指定隐患的治理任务；
     * 从任务项表中进行查询，查询的结果按照计划截止时间升序排列；
     * @param hazardId 危险源ID
     * @return List<TaskItemInfoDto>
     * @author QuCheng Tech
     * @since 2024/11/18
     */
    public List<TaskItemInfoDto> queryTodoByHazardId(String hazardId) {
        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsTaskItem::getHazardid, hazardId);

        //查询待办
        //任务状态：执行完成为false并且取消/终止为false
        wrapper.eq(EhsTaskItem::getHasfinish, false)
                .eq(EhsTaskItem::getHasend, false);

        wrapper.orderByAsc(EhsTaskItem::getPlanendtm);

        List<EhsTaskItem> ens = repository.selectList(wrapper);
        if (CollectionUtils.isNotEmpty(ens)) {
            return EhsTaskItemMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 查询任务项Entity集合，可以指定组织代码或单元ID、任务项状态
     *
     * @param orgCode           组织代码，可以为空
     * @param unitid            单元ID，可以为空
     * @param beginTime         起始时间
     * @param endTime           截止时间
     * @param status            任务项状态:任务状态：0-待办，1-已办，其他-全部
     * @param taskCategoryTypes 任务大类：可以为1个或多个，为空表示所有任务类型
     * @return java.util.List<qc.module.ehs.entity.EhsTaskItem>
     * @author QuCheng Tech
     * @since 2024/12/13
     */
    public List<EhsTaskItem> queryTaskItemEntities(String orgCode, String unitid, Date beginTime, Date endTime, int status, List<EhsTaskCategoryTypeEnum> taskCategoryTypes) throws QCPromptException {
        if (StringUtils.isBlank(orgCode) && StringUtils.isBlank(unitid))
            throw new QCPromptException("查询任务项的组织机构代码和单元ID不能同时为空");

        LambdaQueryWrapper<EhsTaskItem> wrapper = new LambdaQueryWrapper<>();
        //组织机构代码，如果不为空判断相等
        if (StringUtils.isNotBlank(orgCode))
            wrapper.eq(EhsTaskItem::getOrgcode, orgCode);
        //单元ID，如果不为空判断相等
        if (StringUtils.isNotBlank(unitid))
            wrapper.eq(EhsTaskItem::getUnitid, unitid);
        //判断查询的任务状态:0-待办，1-已办，其他-全部
        if (status == 0x0) {
            //待办：执行完成为false并且取消/终止为false
            wrapper.eq(EhsTaskItem::getHasfinish, false)
                    .eq(EhsTaskItem::getHasend, false);
        } else if (status == 0x1) {
            //已办：执行完成为true或者取消/终止为true
            wrapper.and(q -> {
                q.eq(EhsTaskItem::getHasfinish, true).or()
                        .eq(EhsTaskItem::getHasend, true);
            });
        } else {
            //查询任务项状态为全部，不需要进行过滤
        }
        //如果有任务大类数组，进行过滤
        if (taskCategoryTypes != null && taskCategoryTypes.size() > 0x0)
            wrapper.in(EhsTaskItem::getTasktype, taskCategoryTypes);
        
        /*任务项的时间条件判断需要考虑以下几种不同情况：
            1.查询的起止时间前后都包含计划时间，查询时间段包含整个计划时间段；
            pbtm>=tm1 and petm<=tm2
            2.查询的起止时间前后都被计划时间包含，查询的时间段是计划时间段中间的部分时间；
            pbtm<=tm1 and petm>=tm2
            3.查询的起始时间被计划时间包含，查询时间段包含计划时间中的前部分时间；
            查询的截止时间被计划时间包含，查询时间段包含计划时间中的后部分时间；
            pbtm<=tm2 and petm>=tm1
        */
        wrapper.and(q -> {
            (q.ge(EhsTaskItem::getPlanbegintm, beginTime).le(EhsTaskItem::getPlanendtm, endTime)).or()
                    .le(EhsTaskItem::getPlanbegintm, beginTime).ge(EhsTaskItem::getPlanendtm, endTime).or()
                    .le(EhsTaskItem::getPlanbegintm, endTime).ge(EhsTaskItem::getPlanendtm, beginTime);
        });

        return repository.selectList(wrapper);
    }

    /**
     * 更新指定的任务项对应的报告ID
     *
     * @param taskItemId 任务项ID
     * @param fileId 报告文件ID
     * @return java.lang.String
     * @author QuCheng Tech
     * @since 2025/3/6
     */
    public String updateReport(String taskItemId, int fileId) {
        if (StringUtils.isBlank(taskItemId))
            return QCUnifyReturnValue.Warn("任务项ID不能为空");
        if (fileId < 0x1)
            return QCUnifyReturnValue.Warn("报告文件ID无效");

        LambdaUpdateWrapper<EhsTaskItem> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(EhsTaskItem::getItemid, taskItemId)
                .set(EhsTaskItem::getRptid, fileId);

        if (repository.update(null, wrapper) != 0x1)
            return QCUnifyReturnValue.Warn("更新任务项报告文件ID失败");

        return QCUnifyReturnValue.Success();
    }
}
